package IC.asm.printer;

import java.util.List;

import IC.asm.*;
import IC.asm.operands.*;

public class IntelPrinter extends ASMPrinter {

	private IntelPrinter() {};

	public String visit(Instruction that, Object d) {
		StringBuffer s = new StringBuffer();
		s.append("\t");
		s.append(that.getOp());
		s.append(" \t\t");
		if (Instruction.Ops.ControlFlowOps.contains(that.getOp())) {
			s.append(that.getSource().accept(this, ""));
		}
		else {
			if (that.getDest() != null) {
				s.append(that.getDest().accept(this, null));
				if (that.getSource() != null)
					s.append(", ");
			}
			if (that.getSource() != null)
				s.append(that.getSource().accept(this, null));
		}
		return s.toString();
	}

	public static void Print(List<ASMEntry> asm) {
		IntelPrinter p = new IntelPrinter();
		System.out.println(".intel_syntax noprefix");
		for (ASMEntry e: asm) {
			System.out.println(e.accept(p, null));
		}
	}

	public String visit(MemOperand that, Object d) {
		StringBuffer s = new StringBuffer();
		s.append("dword ptr [");
		s.append(that.getBase().accept(this, d));
		if (that.getIndex() != null) {
			s.append(" + ");
			s.append(that.getIndex().accept(this, d));
			if (that.getScale() != 1)
				s.append("*"+that.getScale());
		}
		if (that.getOffset() != 0) {
			int offs = that.getOffset();
			s.append( (offs>0) ? " + " : " - ");
			s.append(Math.abs(offs));
		}
		s.append("]");
		return s.toString();
	}


	public String visit(MachineReg that, Object d) {
		return that.getReg().toString();
	}

	public String visit(IntImmediate that, Object d) {
		return ""+that.getVal();
	}

	public String visit(Label that, Object d) {
		return ((d==null)?"offset ":"")+that.getName();
	}
}
